package com.tz.common.dao;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Repository;
import org.springframework.util.Assert;

import com.tz.platform.dao.BaseDaoImpl;
import com.tz.platform.dao.DaoUtils;
import com.tz.platform.page.PageCondition;
import com.tz.platform.utils.StringUtil;

@Repository("hibernateDao")
public abstract class HibernateDaoImpl<T> extends BaseDaoImpl<T> implements HibernateDao<T> {

	protected transient final Logger log = LoggerFactory.getLogger(getClass());

	@Resource(name="sessionFactory")
	protected SessionFactory sessionFactory;
	
	public Class<T> getEntityClass() {
		return super.getEntityClass(this.getClass());
	}
	
	
	
	@SuppressWarnings("rawtypes")
	@Override
	public PageCondition findByPage(String hql , PageCondition condition) {
		List list = this.queryPage(hql,condition.getPageNo(), condition.getPageSize(), condition);
		condition.setList(list);
//		int count = getCount(hql, condition);
//		condition.setAllCount(count);
		return condition;
	}
	
	
	
	@SuppressWarnings("unchecked")
	public List<T> queryPage(final String ql, final int pageNo, final int pageSize, PageCondition condition) {
		Assert.isTrue(pageNo >= 1, "pageNo should start from 1");
		// Count查询
		Query query = createQueryByCondition(ql, condition);
		query.getNamedParameters();
		int startIndex = (pageNo - 1) * pageSize;
		List<T> list = query.setFirstResult(startIndex).setMaxResults(pageSize).list();
		return list;
	}
	
	/**
	 * 根据查询条件condition查询
	 * @param hql
	 * @param condition
	 * @return
	 */
	@SuppressWarnings("rawtypes")
	private Query createQueryByCondition(final String hql, PageCondition condition) {
		Assert.hasText(hql);
		//处理SQL
		String sql = new DaoUtils().formatHql(hql, condition);
		Query query = getSession().createQuery(sql.replaceAll("%", " "));
		//判断查询条件不为空， 则获取查询信息
		if(condition == null || condition.getParamsCondition()==null){
			return query;
		}
		for(Map.Entry<String, Object> entry : condition.getParamsCondition().entrySet()){
			if(sql.contains(":"+entry.getKey())){
				if(!StringUtil.msIsEmpty(entry.getValue())){
					if(entry.getValue() instanceof String){
						query.setString(entry.getKey(), String.valueOf(entry.getValue()));
					}else{
						query.setParameterList(entry.getKey(), (List)entry.getValue());
					}
				}
			}
		}
		return query;
	}
	
	
}